/*
 * Json2.cpp
 *
 *  Created on: Mar 19, 2009
 *      Author: hua
 */
#include "stdafx.h"

#include <json/Json.hpp>
#include <sstream>
#include <iostream>

using namespace std;
using namespace json;

String json::escape_string(const String& str) {
	String::size_type pos = 0, offset = 0;
	wstringstream ss;
	for (String::const_iterator i = str.begin(); i != str.end(); ++i) {
		Char c = *i;
		switch (c) {			
		case L'\b':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\b";
			offset = ++pos;
			break;			
		case L'\f':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\f";
			offset = ++pos;
			break;			
		case L'\n':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\n";
			offset = ++pos;
			break;
		case L'\r':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\r";
			offset = ++pos;
			break;
		case L'\t':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\t";
			offset = ++pos;
			break;
		case L'\'':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\'";
			offset = ++pos;
			break;
		case L'"':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\\"";
			offset = ++pos;
			break;
		case L'\\':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\\\";
			offset = ++pos;
			break;
		case L'\0':
			if (int len = pos - offset) {
				ss << str.substr(offset, len);
			}
			ss << L"\\0";
			offset = ++pos;
			break;
		default:
			/*if (c < ' ') {
			 if (pos - offset > 0)
			 ss << str.substr(offset, pos);
			 ss << "\\u00%c%c" << JsonObject::hexChars[c >> 4] << JsonObject::hexChars[c & 0xf];
			 offset = ++pos;
			 } else {

			 }*/
			++pos;
			break;
		}
	}
	if (offset > 0) {
		if (int len = pos - offset) {
			ss << str.substr(offset, len);
		}
		return ss.str();
	}
	return str;
}

static void write_json_to_stream(wstringstream& stream,JsonObject* object,int level = 0,const String& name = L""){
	for(int i = 0;i < level;++i){
		stream << L"    ";
	}
	if(!name.empty()){
		stream << name << L":";
	}


	switch(object->type()){
		case JSON_TYPE_NULL:
			stream << L"null";
			break;
		case JSON_TYPE_BOOL:
			stream << (json_cast<bool>(object) ? L"true" : L"false");
			break;
		case JSON_TYPE_INT:
			stream << json_cast<int>(object);
			break;
		case JSON_TYPE_STRING:
			stream << L'"' << json_cast<String>(object) << L'"';
			break;
		case JSON_TYPE_DOUBLE:
			stream << json_cast<double>(object);
			break;
		case JSON_TYPE_OBJECT:
			{
				JObject* o = (JObject*)object;
				stream << L"{\n";
				for(JObject::iterator i = (o->begin());i != (o->end());++ i){
					String name = i->first;
					JsonObject* value = i->second;					
					write_json_to_stream(stream,value,level+1,name);
				}
				for(int i = 0;i < level;++i){
					stream << L"    ";
				}
				stream << L"}";
				break;
			}
		case JSON_TYPE_ARRAY:
			{
				JArray* a = (JArray*)object;
				stream << L"[\n";
				for(JArray::iterator i = a->begin();i != a->end();++ i){					
					write_json_to_stream(stream,*i,level+1);
				}
				for(int i = 0;i < level;++i){
					stream << L"    ";
				}
				stream << L"]";
				break;
			}
		default:
			break;		
	}
	stream << L",\n";
}
void json::print_json_object(JsonObject* object,int level,const String& name){
	wstringstream wss;
	write_json_to_stream(wss,object,level,name);
	wstring s = wss.str();
	wcout << s;
}
